package com.mdisoft.quotogram.utils;

import java.util.List;

import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

public class LocationHelper {
	
	private String TAG = "QUOTOGRAM_LocationHelper";
	
	private Context _context;
	protected Criteria _criteria;
	protected LocationManager _locationManager;
	protected LocationListener _locationListener;
	protected Location _result = null;
		
	
	public LocationHelper(Context context) {
		_context = context;
		_locationListener = locationListener;
		_locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
		_criteria = new Criteria();
		_criteria.setAccuracy(Criteria.ACCURACY_FINE);
		_criteria.setPowerRequirement(Criteria.POWER_LOW);
	}
	
	public Location LastBestLocation() {		
		return LastBestLocation(500, 300000L);
	}
	public Location LastBestLocation(int minDistance, long minTime) {		
		float bestAccuracy = Float.MAX_VALUE;
		long bestTime = Long.MAX_VALUE;
		
		// Iterate through all the providers to get most accurate result 
		// within the acceptable time limit. If no result is found within 
		// minTime, return the newest Location.
		List<String> matchingProviders = _locationManager.getAllProviders();
		if (matchingProviders!=null) {
			for (String provider: matchingProviders) {
				Location location = _locationManager.getLastKnownLocation(provider);			
				if (location != null) {
					float accuracy = location.getAccuracy();
					//long time = System.currentTimeMillis() - location.getTime();
					long time = location.getTime();
				
				
					Log.i(TAG, location.toString());
					Log.i(TAG, "accuracy: " + String.valueOf(accuracy));
					Log.i(TAG, "time: " + String.valueOf(time));
					//Log.i(TAG, "fix time: " + String.valueOf(location.getTime()));
					//Log.i(TAG, "minTime: " + String.valueOf(minTime));
					//Log.i(TAG, "bestTime: " + String.valueOf(bestTime));
					//Log.i(TAG, "bestAccuracy: " + String.valueOf(bestAccuracy));
				
				
					if ((time < minTime && accuracy < bestAccuracy)) {
						_result = location;
						bestAccuracy = accuracy;
						bestTime = time;
					} else if (time > minTime && bestAccuracy == Float.MAX_VALUE && time < bestTime){
						_result = location;
						bestTime = time;
					}
				}
			}
		
			// If the best result is beyond the allowed time limit, or the accuracy of the
			// best result is wider than the acceptable maximum distance, request a single update.
			// This check simply implements the same conditions we set when requesting regular
			// location updates every [minTime] and [minDistance]. 
			if (_locationListener != null && (bestTime > minTime || bestAccuracy > minDistance)) { 
				String provider = _locationManager.getBestProvider(_criteria, true);
				if (provider != null) {
					_locationManager.requestLocationUpdates(provider, 0, 0, _locationListener, _context.getMainLooper());
		    	  
					// remove location updates in case  it takes too long to get GPS fix
					if (provider.equalsIgnoreCase(LocationManager.GPS_PROVIDER)) {
						Handler handler = new Handler();
						handler.postDelayed(new Runnable(){
							public void run() { 
								_locationManager.removeUpdates(_locationListener);	    					  
							}
						}, 30000L);
					}
				}
			}
		}
		return _result;
	}

	
	protected LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			_locationManager.removeUpdates(_locationListener);
		}
		public void onProviderDisabled(String provider) {	}
		public void onProviderEnabled(String provider) {	}
		public void onStatusChanged(String provider, int status, Bundle extras) {	}		
	};
}
